home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / bix02.arc / TRAPIT.PAS < prev    next >
Pascal/Delphi Source File  |  1986-08-04  |  6KB  |  181 lines

  1. {stay-resident program with keyboard intercept}
  2.  
  3. program TrapIt;
  4.  
  5.     { Program installs itself and traps the [ALT] + [ESC] key. }
  6.     { Compile under Turbo Pascal version 3.00 or higher with   }
  7.     { minimun and maximum stack and heap size of about $200.   }
  8.     { Run only as a com file.                                  }
  9.  
  10. const
  11.     hot_key = $01; { Escape key }
  12.  
  13.     keyboard_interrupt       = $09;
  14.     keyboard_data_port       = $60;
  15.     keyboard_control_port    = $61;
  16.     clear_keyboard_bit       = $80;
  17.     interrupt_control_port   = $20;
  18.     end_of_interrupt_command = $20;
  19.     alt_shift_flag_bit       = $08;
  20.  
  21. type
  22.     pointer = ^byte;
  23.  
  24.     address = record
  25.         offset, segment : integer;
  26.     end; {record}
  27.  
  28.     register_pack = record case integer of
  29.         1 : (ax, bx, cx, dx, bp, si, di, ds, es, flags : integer);
  30.         2 : (al, ah, bl, bh, cl, ch, dl, dh : byte);
  31.     end; {record}
  32.  
  33.  
  34. var
  35.     bios_keyboard_flags : byte absolute $0040:$0017;
  36.     registers           : register_pack;
  37.     kb_data, kb_control : byte;
  38.  
  39.  
  40. const
  41.     original_vector : address = (offset:0; segment:0);
  42.     our_ds : integer = 0;
  43.     our_ss : integer = 0;
  44.     our_sp : integer = 0;
  45.     save_ss : integer = 0;
  46.     save_sp : integer = 0;
  47.  
  48.  
  49. function stack_pointer: integer;
  50.     { Returns the contents of sp at time of call. }
  51. begin
  52.     { Stack now looks like: [x,bp,ip,fr]. }
  53.     inline ($89/$E8/      { mov ax,bp     }
  54.             $05/$06/$00/  { add ax,6      }
  55.             $89/$46/$04); { mov [bp+4],ax }
  56. end; {stack_pointer}
  57.  
  58.  
  59. procedure get_vector (interupt : integer; var v);
  60. var
  61.     vector : ^byte absolute v;
  62.     regs : register_pack;
  63. begin
  64.     regs.ah := $35;
  65.     regs.al := interupt;
  66.     msdos (regs);
  67.     vector := ptr(regs.es, regs.bx);
  68. end; {get_vector}
  69.  
  70.  
  71. procedure set_vector (interupt : integer; vector : pointer);
  72. var
  73.     regs : register_pack;
  74. begin
  75.     with regs do begin
  76.         ah := $25;
  77.         al := interupt;
  78.         ds := seg(vector^);
  79.         dx := ofs(vector^);
  80.     end; {with}
  81.     msdos (regs);
  82. end; {set_vector}
  83.  
  84.  
  85. procedure terminate_resident;
  86. var
  87.     regs : register_pack;
  88. begin
  89.     with regs do begin
  90.         ah := $31;
  91.         al := 0;
  92.         dx := memw [cseg - 1 : $0003];
  93.     end; {with}
  94.     msdos (regs);
  95. end; {terminate_resident}
  96.  
  97.  
  98. function alt_key_pressed: boolean;
  99. begin
  100.     alt_key_pressed := (bios_keyboard_flags and alt_shift_flag_bit) <> 0;
  101. end; {alt_key_pressed}
  102.  
  103.  
  104. procedure do_our_thing;
  105. begin
  106.     write ('Gotcha');
  107. end;
  108.  
  109.  
  110. procedure interrupt_service_routine;
  111. begin
  112.     inline ( $5D/                             { pop  bp             }
  113.              $5D/                             { pop  bp             }
  114.              $50/                             { push ax             }
  115.              $53/                             { push bx             }
  116.              $51/                             { push cx             }
  117.              $52/                             { push dx             }
  118.              $56/                             { push si             }
  119.              $57/                             { push di             }
  120.              $55/                             { push bp             }
  121.              $06/                             { push es             }
  122.              $1E/                             { push ds             }
  123.              $2E/$8E/$1E/Our_DS/              { mov  ds,cs:Our_DS   }
  124.              $2E/$8C/$16/Save_SS/             { mov  cs:Save_SS,ss  }
  125.              $2E/$89/$26/Save_SP/             { mov  cs:Save_SP,sp  }
  126.              $2E/$8E/$16/Our_SS/              { mov  ss,cs:Our_SS   }
  127.              $2E/$8B/$26/Our_SP               { mov  sp,cs:Our_sp   }
  128.     );
  129.  
  130.     if (port [keyboard_data_port] = hot_key) and alt_key_pressed then begin
  131.         do_our_thing;
  132.  
  133.         { Reset keyboard. }
  134.         Kb_control := port [Keyboard_control_port];
  135.         port [Keyboard_control_port] := Kb_control or Clear_keyboard_bit;
  136.         port [Keyboard_control_port] := Kb_control;
  137.         port [Interrupt_control_port] := End_of_interrupt_command;
  138.  
  139.         { Return from interrupt. }
  140.         inline ( $2E/$8E/$16/save_ss/             { mov  ss,cs:Save_SS  }
  141.                  $2E/$8B/$26/save_sp/             { mov  sp,cs:Save_SP  }
  142.                  $1F/                             { pop  ds             }
  143.                  $07/                             { pop  es             }
  144.                  $5D/                             { pop  bp             }
  145.                  $5F/                             { pop  di             }
  146.                  $5E/                             { pop  si             }
  147.                  $5A/                             { pop  dx             }
  148.                  $59/                             { pop  cx             }
  149.                  $5B/                             { pop  bx             }
  150.                  $58/                             { pop  ax             }
  151.                  $CF                              { iret                }
  152.         );
  153.     end else
  154.         { Pass interrupt on to original handler. }
  155.         inline ( $2E/$8E/$16/save_ss/             { mov  ss,cs:Save_SS  }
  156.                  $2E/$8B/$26/save_sp/             { mov  sp,cs:Save_SP  }
  157.                  $1F/                             { pop  ds             }
  158.                  $07/                             { pop  es             }
  159.                  $5D/                             { pop  bp             }
  160.                  $5F/                             { pop  di             }
  161.                  $5E/                             { pop  si             }
  162.                  $5A/                             { pop  dx             }
  163.                  $59/                             { pop  cx             }
  164.                  $5B/                             { pop  bx             }
  165.                  $58/                             { pop  ax             }
  166.                  $2E/$FF/$2E/original_vector      { jmp  far Original_V }
  167.         );
  168. end; {interrupt_service_routine}
  169.  
  170.  
  171. begin
  172.     our_ds := dseg;
  173.     our_ss := sseg;
  174.     our_sp := stack_pointer;
  175.  
  176.     get_vector (keyboard_interrupt, original_vector);
  177.     set_vector (keyboard_interrupt, ptr(cseg, ofs(interrupt_service_routine)));
  178.  
  179.     terminate_resident;
  180. end.
  181.